package com.ladybug.flow.modules.flow.controller;

import cn.hutool.http.HttpResponse;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ladybug.flow.common.exception.customexceptions.ServiceException;
import com.ladybug.flow.common.exception.enums.ErrorEnum;
import com.ladybug.flow.common.vo.ResponseResult;
import com.ladybug.flow.modules.flow.domain.DTO.NewModel;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author xianglongfei
 * @description
 * @createDate 2023/1/10 14:44
 */
@RestController
@RequestMapping("/flow")
@Slf4j
public class FlowController {
    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    HttpServletResponse httpServletResponse;

    @GetMapping("/deploy/{id}")
    public ResponseResult deploy(@PathVariable String id) throws IOException {
        //获取模型
        Model modelData = repositoryService.getModel(id);
        byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());
        if (bytes == null) {
            return ResponseResult.error(502,"模型数据为空，请先设计流程并成功保存，再进行发布。");
        }
        JsonNode modelNode = new ObjectMapper().readTree(bytes);
        BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
        if (model.getProcesses().size() == 0) {
            return ResponseResult.error(502,"数据模型不符要求，请至少设计一条主线流程。");
        }

        Collection<FlowElement> flowElements = model.getMainProcess().getFlowElements();
        for(FlowElement e : flowElements) {
            log.info("flowelement id:" + e.getId() + "  name:" + e.getName() + "   class:" + e.getClass().toString());
        }

        byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model);

        //发布流程
        String processName = modelData.getName() + ".bpmn20.xml";
        Deployment deployment = repositoryService.createDeployment()
                .name(modelData.getName())
                .addString(processName, new String(bpmnBytes, "UTF-8"))
                .deploy();
        modelData.setDeploymentId(deployment.getId());
        repositoryService.saveModel(modelData);
        return ResponseResult.success("发布成功！");
    }

    /**
     * @param id id
     * @description: 导出模型
     * @Author: xianglongfei
     * @Date: 2023/01/21
     */
    @GetMapping("/export/{id}")
    public void exportModel(@PathVariable String id) throws IOException {
        Model model = repositoryService.getModel(id);
        if(model == null){
            throw new ServiceException(ErrorEnum.NO_MODEL_FOND);
        }
        BpmnJsonConverter jsonConverter = new BpmnJsonConverter();
        JsonNode editorNode = objectMapper.readTree(repositoryService.getModelEditorSource(id));
        BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode);
        BpmnXMLConverter xmlConverter = new BpmnXMLConverter();
        byte[] bpmnBytes = xmlConverter.convertToXML(bpmnModel,"UTF-8");
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bpmnBytes);
        String fileName = URLEncoder.encode(model.getName())+"."+model.getVersion()+".bpmn20.xml";
        System.out.println(fileName);
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.setContentType("application/xml");
        httpServletResponse.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        IOUtils.copy(byteArrayInputStream,httpServletResponse.getOutputStream());
        httpServletResponse.flushBuffer();
    }

    /**
     * @return {@code ResponseResult }
     * @description: 获取所有发布流程
     * @Author: xianglongfei
     * @Date: 2023/01/28 11:19:28
     */
    @GetMapping("/deployment")
    public ResponseResult deploymentList(){
        List<ProcessDefinition> deployments = repositoryService.createProcessDefinitionQuery().list();
        List<Map<String, Object>> pdResult = new ArrayList<>();
        for(ProcessDefinition processDefinition : deployments ){
            Map<String, Object> pdMap = new HashMap<>();
            pdMap.put("id", processDefinition.getId());
            pdMap.put("key", processDefinition.getKey());
            pdMap.put("name", processDefinition.getName());
            pdMap.put("version", processDefinition.getVersion());
            pdMap.put("deploymentId", processDefinition.getDeploymentId());
            pdResult.add(pdMap);
        }
     return ResponseResult.success(pdResult);
    }




}
